package com.example.kotlindemo

import android.util.AttributeSet

/**
 * @author Lmy
 * @功能:
 * @Creat 2020/5/14 14:08
 * @Compony 永远相信美好的事物即将发生
 */


/**
 * abstract     抽象类
final        类不可继承，默认属性
enum         枚举类
open         类可继承，类默认是final的
annotation   注解类

private     仅在同一个文件中可见
protected   同一个文件中或子类可见
public      所有调用的地方都可见
internal    同一个模块中可见
 *
 */
open class ChouXiangClass {
    open fun f() {}

    /**
     * 嵌套类
     *
     */
    class Outer {                  // 外部类
        private val bar: Int = 1
        var v = "成员属性"

        class Nested {             // 嵌套类
            fun foo() = 2
        }
//    调用嵌套类的方式如下Outer.Nested().foo()  嵌套类无法访问外部类的成员变量

        /**嵌套内部类  用inner修饰**/
        inner class Inner {
            fun foo() = bar  // 访问外部类成员
            fun innerTest() {
                var o = this@Outer //获取外部类的成员变量 这里o相当于Outer类的引用
                println("内部类可以引用外部类的成员，例如：" + o.v + o.bar)
            }
        }
    }
}

/**
 * 抽象是面向对象编程的特征之一，类本身，或类中的部分成员，都可以声明为abstract的。抽象成员在类中不存在具体的实现。

注意：无需对抽象类或抽象成员标注open注解。
 *
 */


open class Person(var name: String, var age: Int) {
    // 基类
    open var y: String = "A"
    open fun personMain() {
        println("我毕业了")
    }

}

//如果子类有主构造函数， 则基类必须在主构造函数中立即初始化。
class Student(name: String, age: Int, var no: String, var score: Int) : Person(name, age) {
    override var y: String = "B"

    override fun personMain() {
        super.personMain()
        //        print("重写了我毕业了")

    }
}

//如果子类没有主构造函数，则必须在每一个二级构造函数中用 super 关键字初始化基类，
// 或者在代理另一个构造函数。初始化基类时，可以调用基类的不同构造方法。
class Student1 : Person {
    constructor(name: String, age: Int) : super(name, age)
}


// 测试
fun main(args: Array<String>) {
    val s = Student("Runoob", 18, "S12346", 89)
    println("学生名： ${s.name}")
    println("年龄： ${s.age}")
    println("学生号： ${s.no}")
    println("成绩： ${s.score}")
    s.personMain()

    val c = C()
    c.f();

}


open class A {
    open fun f() {
        print("A\n")
    }

    fun a() {
        print("a\n")
    }
}

interface B {
    fun f() {
        print("B\n")
    } //接口的成员变量默认是 open 的

    fun b() {
        print("b\n")
    }

    fun c()
}

class C() : A(), B {
    override fun c() {
    }

    override fun b() {
        super<B>.b()
    }

    override fun f() {
        super<A>.f()//调用 A.f()
        super<B>.f()//调用 B.f()
    }
}